package cn.it.infrastructure.domain.service.impl;

import cn.it.infrastructure.domain.service.IUserService;
import cn.it.infrastructure.domain.valobj.AddressVO;
import cn.it.infrastructure.domain.valobj.BuyVO;
import cn.it.infrastructure.domain.valobj.LoginVO;
import cn.it.infrastructure.domain.valobj.OrderVO;
import cn.it.infrastructure.mapper.IGoodsMapper;
import cn.it.infrastructure.mapper.IOrderMapper;
import cn.it.infrastructure.mapper.IUserAndGoodsMapper;
import cn.it.infrastructure.mapper.IUserMapper;
import cn.it.infrastructure.po.TbGoods;
import cn.it.infrastructure.po.TbOrder;
import cn.it.infrastructure.po.TbUser;
import cn.it.infrastructure.po.TbUserAndGoods;
import cn.it.infrastructure.type.common.MessageConstant;
import cn.it.infrastructure.type.exception.AppException;
import cn.it.infrastructure.type.properties.WeChatProperties;
import cn.it.infrastructure.type.util.HttpClientUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author Mzq
 * @description
 * @createTime 2024/7/5
 */
@Service
public class UserServiceImpl implements IUserService {

    //微信服务接口地址
    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";


    private WeChatProperties weChatProperties;
    private IUserMapper userMapper;
    private IOrderMapper orderMapper;
    private IUserAndGoodsMapper userAndGoodsMapper;


    @Resource
    private IGoodsMapper goodsMapper;

    public UserServiceImpl(WeChatProperties weChatProperties, IUserMapper userMapper, IOrderMapper orderMapper, IUserAndGoodsMapper userAndGoodsMapper) {
        this.weChatProperties = weChatProperties;
        this.userMapper = userMapper;
        this.orderMapper = orderMapper;
        this.userAndGoodsMapper = userAndGoodsMapper;
    }


    @Override
    public TbUser wxLogin(LoginVO loginVO) {
        //获取用户唯一标识openId
        String openid = getOpenid(loginVO.getOpenId());

        //判断openid是否为空，如果为空表示登陆失败，抛出业务异常
        if (openid == null) {
            throw new AppException(MessageConstant.LOGIN_FAILED);
        }
        //判断当前用户是否为新用户
        TbUser user = new TbUser();
        user = userMapper.selectGetByOpenid(openid);

        //如果是新用户，自动完成注册
        if (user == null) {
            TbUser tbUser = TbUser.builder()
                    .nickName(loginVO.getNickName())
                    .openId(openid)
                    .imageUrl(loginVO.getImageUrl())
                    .sessionKey(loginVO.getSessionKey())
                    .token(loginVO.getToken())
                    .address(null)
                    .phone(null)
                    .status(1)
                    .userRights(0)
                    .description(null)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            userMapper.insert(tbUser);
            //返回这个用户对象
            return tbUser;
        } else {
            //返回这个用户对象
            return user;
        }


    }

    @Override
    public OrderVO placeOrder(BuyVO buyVO) {

        String openId  = getOpenid(buyVO.getOpenId());

        TbUser user = userMapper.selectGetByOpenid(openId);

        TbOrder order = new TbOrder();
        order.setGoodsId(buyVO.getGoodsId());
        order.setUserId(user.getId());
        order.setStatus("代发货");
        order.setCreateTime(new Date());

        // 存储订单
        int id = orderMapper.insertSelective(order);
        order.setId(id);

        String goods = buyVO.getGoodsId();
        StringBuilder goodsName = new StringBuilder();

        Long[] extractNumbers = extractNumbers(goods);
        BigDecimal price = BigDecimal.valueOf(0);
        for (Long extractNumber : extractNumbers) {
            TbGoods goodById = goodsMapper.getRealPriceById(extractNumber);
            BigDecimal realPriceById = BigDecimal.valueOf(goodById.getRealPrice());
            price.add(realPriceById);
            goodsName.append(goodById.getName());
        }

        String orderContent = goodsName.toString();

        OrderVO orderVO = OrderVO.builder()
                .id(order.getId())
                .goodsId(order.getGoodsId())
                .userId(order.getUserId())
                .price(price)
                .orderContent(orderContent)
                .build();


        return orderVO;
    }

    @Override
    public List<TbGoods> userFavorites(Long id) {

        List<TbUserAndGoods> andGoodsList = userAndGoodsMapper.userFavorites(id);

        List<TbGoods> tbGoodsList = new ArrayList<>(andGoodsList.size());

        for (TbUserAndGoods tbUserAndGoods : andGoodsList) {
            TbGoods tbGoods = goodsMapper.selectByPrimaryKey(tbUserAndGoods.getGoodsId());
            tbGoodsList.add(tbGoods);
        }

        return tbGoodsList;
    }

    @Override
    public void updateAddress(AddressVO addressVO) {

        String openId = getOpenid(addressVO.getOpenId());
        TbUser user1 = userMapper.selectGetByOpenid(openId);
        TbUser user = TbUser.builder()
                .id(user1.getId())
                .openId(addressVO.getOpenId())
                .address(addressVO.getAddress())
                .phone(addressVO.getPhone())
                .build();
        userMapper.updateAddress(user);
    }


    /**
     * 调用微信接口服务，获取当前微信用户的openid
     *
     * @param code
     * @return
     */
    private String getOpenid(String code) {
        //调用微信接口服务，获得当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);

        JSONObject jsonObject = JSON.parseObject(json);
        String openid = jsonObject.getString("openid");
        return openid;
    }

    /**
     * 解析包含商品id的字符串
     *
     * @param input
     * @return
     */
    private Long[] extractNumbers(String input) {
        // 正则表达式，匹配一个或多个数字
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(input);

        // 创建一个列表来存储提取的数字
        List<Long> numbersList = new ArrayList<>();

        // 使用正则表达式找到所有匹配的数字
        while (matcher.find()) {
            // 将匹配的字符串转换为Long并添加到列表中
            // 这里使用Long.parseLong以确保数字不会超出Long的范围
            numbersList.add(Long.parseLong(matcher.group()));
        }

        // 将ArrayList转换为Long数组
        Long[] numbersArray = new Long[numbersList.size()];
        numbersList.toArray(numbersArray);

        return numbersArray;
    }

}
